package at.sm1.trainclassifier2000;

public class FeatureVector {
	public enum FeatureType
	{		
		AmountRed(0,"AmountRed"),
		AmountGreen(1,"AmountGreen"),
		AmountBlue(2,"AmountBlue"),
		AmountWhite(3,"AmountWhite"),
		Regularity(4,"Regularity"),
		FEATURE_COUNT(5,"Feature_Count");
		
		public static FeatureType getFeatureTypeFromIndex(int index)
		{
			switch(index)
			{
			case 0: return AmountRed;
			case 1: return AmountGreen;
			case 2: return AmountBlue;
			case 3: return AmountWhite;
			case 4: return Regularity;
			default: return FEATURE_COUNT;
			}
		}
		
		private int index;
		private String name;
		
		FeatureType(int index, String name)
		{
			this.index = index;
			this.name = name;
		}
		
		public int getIndex()
		{
			return index;
		}
		
		public String toString()
		{
			return name;
		}
	}
	
	private double features[];
	
	public FeatureVector()
	{
		features = new double[FeatureType.FEATURE_COUNT.getIndex()];
		
		for(int i=0; i<features.length; i++)
			features[i] = 0.0f;
	}
	
	public double[] getFeatures()
	{
		return features;
	}
	
	public double getFeature(FeatureType type)
	{
		return features[type.getIndex()];
	}
	
	public void setFeature(FeatureType type, double value)
	{
		features[type.getIndex()] = value;
	}
	
	public static FeatureVector sub(FeatureVector v1, FeatureVector v2)
	{
		FeatureVector out = new FeatureVector();
		for(int i=0; i<FeatureType.FEATURE_COUNT.getIndex(); i++)
		{
			FeatureType type = FeatureType.getFeatureTypeFromIndex(i);
			out.setFeature(type, v1.getFeature(type) - v2.getFeature(type));
		}
		return out;
	}
	
	public double length()
	{
		double sum = 0.0f;
		
		for(int i=0; i<features.length; i++)
		{
			sum += Math.pow(features[i], 2.0f);
		}
		
		sum = Math.sqrt(sum);
		
		return sum;
	}
	
	public double getEuclideanDistance(FeatureVector other)
	{
		return getEuclideanDistance(this, other);
	}
	
	public static double getEuclideanDistance(FeatureVector v1, FeatureVector v2)
	{
		return FeatureVector.sub(v1, v2).length();
	}
	
	public static FeatureVector interpolate(FeatureVector v1, FeatureVector v2, double ratio)
	{
		FeatureVector out = new FeatureVector();
		
		for(int i=0; i<FeatureType.FEATURE_COUNT.getIndex(); i++)
		{
			FeatureType type = FeatureType.getFeatureTypeFromIndex(i);
			out.setFeature(type, v1.getFeature(type) * ratio + v2.getFeature(type) * (1.0 - ratio));
		}
		
		return out;
	}
	
	public String toString()
	{
		String out = "";
		
		for(int i=0; i<FeatureType.FEATURE_COUNT.getIndex(); i++)
		{
			out += FeatureType.getFeatureTypeFromIndex(i).toString() + ": " + 
					Double.toString(features[i]) + ";";
		}
		
		return out;
	}
}
